{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 执行顺序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [],
   "source": [
    "def consumer():\n",
    "    status = True\n",
    "    while True:\n",
    "        print(123)\n",
    "        n = yield status\n",
    "        print(456)\n",
    "        print(\"我拿到了{}!\".format(n))\n",
    "\n",
    "# 刚创建并不会执行任何部分        \n",
    "c = consumer()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "开始从头执行到 yield语句，并返回yield 后面表达式的值，然后挂起"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 180,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以后的每次调用，从上次yield 语句那一行开始唤醒，\n",
    "\n",
    "如果有赋值操作`（n= yield xxx) `, 先执行赋值，再往下运行完循环体内的部分，\n",
    "\n",
    "然后执行到新的一轮循环，卡到yield 语句，再挂起。\n",
    "\n",
    "如此重复。\n",
    "\n",
    "注：\n",
    "\n",
    "1. 赋值部分`（n= yield xxx) `，是调用生成器的 `.send(n)` 方法传递过去的，但是你必须先执行 `.send(None)`\n",
    "\n",
    "2. 调用`.send()` 方法跟 `next()`，都会使生成器进行新一轮的内部循环"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "456\n",
      "我拿到了None!\n",
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 181,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {},
   "outputs": [],
   "source": [
    "def consumer():\n",
    "    status = True\n",
    "    while True:\n",
    "        print(123)\n",
    "        n = yield status\n",
    "        print(456)\n",
    "        print(\"我拿到了{}!\".format(n))\n",
    "\n",
    "c = consumer()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "c.send(None)，这条语句的作用是将consumer（即变量c，它是一个generator）中的语句推进到第一个yield语句出现的位置.\n",
    "\n",
    "程序停留在n = yield status的位置（注意：此时这条语句还没有被执行）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 190,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c.send(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "456\n",
      "我拿到了Apple!\n",
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 188,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c.send('Apple')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "456\n",
      "我拿到了None!\n",
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "456\n",
      "我拿到了2!\n",
      "123\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 166,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c.send(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 生产者-消费者"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我拿到了5!\n",
      "我拿到了4!\n",
      "我拿到了3!\n",
      "我只要3,4,5就行啦\n",
      "程序结束\n"
     ]
    }
   ],
   "source": [
    "def consumer():\n",
    "    status = True\n",
    "    while True:\n",
    "        n = yield status\n",
    "        print(\"我拿到了{}!\".format(n))\n",
    "        if n == 3:\n",
    "            status = False\n",
    "\n",
    "def producer(consumer):\n",
    "    n = 5\n",
    "    while n > 0:\n",
    "    # yield给主程序返回消费者的状态\n",
    "        yield consumer.send(n)\n",
    "        n -= 1\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    c = consumer()\n",
    "    c.send(None)\n",
    "    p = producer(c)\n",
    "    for status in p:\n",
    "        if status == False:\n",
    "            print(\"我只要3,4,5就行啦\")\n",
    "            break\n",
    "    print(\"程序结束\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nbTranslate": {
   "displayLangs": [
    "*"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "fr",
   "useGoogleTranslate": true
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "position": {
    "height": "227.86px",
    "left": "1216px",
    "right": "20px",
    "top": "120px",
    "width": "300px"
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
